package com.springboot2.shiro.web.controller;

import com.springboot2.shiro.comm.entity.RespResult;
import com.springboot2.shiro.mgt.token.CipherFreeToken;
import com.springboot2.shiro.web.entity.Login;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.function.Function;

/**
 * LoginController
 *
 * @author Archx[archx@foxmail.com]
 * at 2018/7/13 22:16
 */
@RestController
@Slf4j
public class LoginController {

    /**
     * 渠道登录，免密登录
     *
     * @param request HTTP 请求体体
     * @return JSON
     */
    @GetMapping(value = "/login")
    public RespResult login(HttpServletRequest request) {
        String code = request.getParameter("code");

        // 通过code，或其他方式进行渠道认证
        Function<String, String> channel = (r -> "admin");

        String login = channel.apply(code);
        // 执行免密码登录
        return doLogin(new CipherFreeToken(login)).build();
    }

    /**
     * 无状态登录
     *
     * @param login 登录信息
     * @return json
     */
    @PostMapping(value = "/login")
    public RespResult login(Login login) {

        UsernamePasswordToken token = new UsernamePasswordToken(login.getUsername(),
                                                                login.getPassword(),
                                                                login.isRememberMe());
        RespResult.Builder resp = doLogin(token);

        return resp.build();
    }

    /**
     * 执行登录
     *
     * @param token 令牌
     * @return 结果
     */
    private RespResult.Builder doLogin(AuthenticationToken token) {
        // 尝试登录
        Subject            subject = SecurityUtils.getSubject();
        RespResult.Builder builder = RespResult.builder();

        try {
            subject.login(token);
            builder.code(RespResult.Code.Success).data("token", subject.getSession().getId()).message("ok");
        } catch (IncorrectCredentialsException e) {
            builder.code(RespResult.Code.Failure).message("密码错误");
        } catch (LockedAccountException e) {
            builder.code(RespResult.Code.Failure).message("账号锁定，无法登录");
        } catch (UnknownAccountException e) {
            builder.code(RespResult.Code.Failure).message("用户名或密码错误");
        } catch (AuthenticationException e) {
            builder.code(RespResult.Code.Failure).message("认证失败，" + e.getMessage());
        } catch (Exception e) {
            builder.code(RespResult.Code.Exception).message(e.getMessage());
        }

        return builder;
    }

}
